package listener

import (
    "errors"
    "fmt"
    "path"
    "strconv"
    "strings"
    "time"
    
    "gorm.io/gorm"
    
    "collecter/app/common/enum"
    "collecter/app/common/helper"
    "collecter/app/event/interfaces"
    "collecter/app/model"
)

type CreateCollect struct {
    EventName   string
    SubjectId   int64
    ExtraParams string
}

func (cc CreateCollect) SetValue(eventName string, subjectId int64, extraParams string) interfaces.EventInterfacer {
    cc.EventName = eventName
    cc.SubjectId = subjectId
    cc.ExtraParams = extraParams
    return cc
}

func (cc CreateCollect) Handle() error {
    fmt.Println("CreateCollect event is listen ... ")
    fmt.Printf(" CreateCollect-->Handle: %+v\n", cc)
    
    collect := model.Collects{Id: cc.SubjectId}
    if err := helper.Db.Where(&collect).First(&collect).Error; err != nil {
        errmsg := "新增收藏内容事件监听失败：查询收藏记录失败。errmsg：" + err .Error()
        helper.Logger.WithField("appert", "eventerr").Error(errmsg)
        return nil
    }
    if 1 == collect.ContentType {
        // 收藏的内容不是文件
        return nil
    }
    collect.SourceUrl = collect.Content
    if 2 == collect.ContentType {
        collect.Ext = helper.GetExt(collect.Content)
        if err := handleCollectFile(&collect, "新增"); err != nil {
            return nil
        }
    } else if 3 == collect.ContentType {
        collect.Remark = "收藏内容是一个 url "
    }
    
    if err := helper.Db.Save(&collect).Error; err != nil {
        errmsg := "新增收藏内容事件监听失败：更新收藏记录失败。errmsg：" + err .Error()
        helper.Logger.WithField("appert", "eventerr").Error(errmsg)
        return nil
    }
    return nil
}


func handleCollectFile(collect *model.Collects, action string) error {
    httperr, resp := helper.Request(collect.Content, "head", nil, nil)
    if httperr != nil {
        errmsg := action + "收藏内容事件监听失败：获取文件信息失败。errmsg：" + httperr .Error()
        helper.Logger.WithField("appert", "eventerr").Error(errmsg)
        return httperr
    }
    
    if length, err := strconv.Atoi(resp.Header.Get("Content-Length")); err != nil {
        errmsg := action + "收藏内容事件监听失败：转换文件大小单位失败。errmsg：" + httperr .Error()
        helper.Logger.WithField("appert", "eventerr").Error(errmsg)
        return err
    } else {
        collect.Filesize = helper.HumanSize(int64(length))
    }
    collect.Remark = "收藏内容是一个文件，文件类型为：" + resp.Header.Get("Content-Type")
    
    t := time.Now()
    saveFile := "static/collects/" + t.Format(strings.Replace(time.DateOnly, "-", "/", -1))
    fullPath := enum.ROOT_DIR + saveFile
    _, filename := path.Split(collect.Content)
    fullPath += "/" + filename
    saveFile += "/" + filename
    if err := helper.DownloadRemoteFile(fullPath, collect.Content); err != nil {
        errmsg := action + "收藏内容事件监听失败：写入文件内容失败。errmsg：" + httperr .Error()
        helper.Logger.WithField("appert", "eventerr").Error(errmsg)
        return err
    }
    collect.Content = saveFile
    abstract := helper.MakeFileUUID(fullPath)
    otherCollect := model.Collects{Abstract: abstract}
    if err := helper.Db.Where(&otherCollect).First(&otherCollect).Error; err != nil {
        if !errors.Is(err, gorm.ErrRecordNotFound) {
            errmsg := action + "收藏内容事件监听失败：查询重复文件失败。errmsg：" + httperr .Error()
            helper.Logger.WithField("appert", "eventerr").Error(errmsg)
            return err
        }
        
    } else {
        /* 收藏的文件已经存在，删除刚刚下载的文件 */
        collect.Content = otherCollect.Content
        _ = helper.Unlink(fullPath)
    }
    collect.Abstract = abstract
    return nil
}